package cn.xianshu.order.service.impl;

import cn.xianshu.basic.exception.BasicException;
import cn.xianshu.basic.service.impl.BasicServiceImpl;
import cn.xianshu.basic.util.LoginContextUtil;
import cn.xianshu.order.domain.OrderAddress;
import cn.xianshu.order.domain.OrderPet;
import cn.xianshu.order.domain.OrderPetDetail;
import cn.xianshu.order.dto.InsertOrderDto;
import cn.xianshu.order.service.IOrderAddressService;
import cn.xianshu.order.service.IOrderPetDetailService;
import cn.xianshu.order.service.IOrderPetService;
import cn.xianshu.pay.domain.PayBill;
import cn.xianshu.pay.service.IPayBillService;
import cn.xianshu.pet.domain.Pet;
import cn.xianshu.pet.service.IPetService;
import cn.xianshu.quartz.job.OrderExpireJob;
import cn.xianshu.quartz.service.IQuartzService;
import cn.xianshu.user.domain.Logininfo;
import cn.xianshu.user.domain.UserAddress;
import cn.xianshu.user.mapper.UserAddressMapper;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

@Service
public class OrderPetServiceImpl extends BasicServiceImpl<OrderPet> implements IOrderPetService {


    @Autowired
    private IPetService petService;

    @Autowired
    private IPayBillService payBillService;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private IOrderPetDetailService orderPetDetailService;

    @Autowired
    private IOrderAddressService orderAddressService;

    @Autowired
    private IQuartzService quartzService;


    /**
     * 下单
     * 1.校验数据
     * 2.查询宠物的数据 判断宠物是否上架
     * 3.查询用户的收货地址，支付方式
     * 4.创建订单号，计算支付超时时间，保存订单数据
     * 5.保存订单明细
     * 6.保存订单地址
     * 7.宠物表库存 -1 什么时候扣库存  下单的时候减库存  取消就加上
     * @param dto
     * @return
     */
    @Override
    public String placeOrder(InsertOrderDto dto) {
       //========================================校验参数================================================
        // 1.校验参数
        Long addressId = dto.getAddressId(); // 取出用户地址的id
        Integer petType = dto.getPayType();// 获取支付方式
        Long petId = dto.getPetId();// 获取宠物id
        /*if (addressId == null || petType == null || petId == null){
            throw new BasicException("无效的商品!");
        }*/
        if (petType == null){
            throw new BasicException("无效的支付方式!");
        }
        if (addressId == null){
            throw new BasicException("无效的地址!");
        }
        if (petId == null){
            throw new BasicException("无效的宠物!");
        }

        // ========================================宠物和地址查询===================================================

        // 2. 查询宠物信息，判断是否上线
        // 宠物类型 宠物店铺
        Pet pet = null;

        // =======================================扣减宠物库存========================================
        // 7.宠物表  库存-1 下单的时候将库存 -1
        synchronized (this){ // 防止超卖上锁
            pet = petService.selectOnLineById(petId);
            if (pet == null){
                throw new BasicException("无效的宠物地址!");
            }

            // 线程
            if (pet.getStore_number() == null || pet.getStore_number().intValue() == 0){
                throw new BasicException("亲，没货啦，下次手速快一点哟!");
            }
            pet.setStore_number(pet.getStore_number() - 1);
            petService.update(pet);
        }

        // 3.查询用户的收货地址，支付方式
        UserAddress userAddress = userAddressMapper.selectById(addressId);
        if (userAddress == null){
            throw new BasicException("无效的地址!");
        }
        // =================================构建， 保存订单======================================
        // 4.创建订单号
        String orderNo = UUID.randomUUID().toString().replaceAll("-", "");
        Date now = new Date();
        // 计算支付超时时间,保存订单数据
        // TODO :测试使用   addMinutes
        Date payExpireTime = DateUtils.addSeconds(now, 30);
        // 保存订单
        OrderPet orderPet = new OrderPet();

        orderPet.setDigest("购买:" + pet.getName()+ "下单");
        orderPet.setCreateTime(now);
        // 支付超时时间
        orderPet.setPayExpireTime(payExpireTime);
        // 订单号
        orderPet.setOrderSn(orderNo);
        orderPet.setPayType(petType);
        // 状态，待支付
        orderPet.setState(OrderPet.STATE_WAIT_PAY);
        orderPet.setTotalCount(1);
        // 金额加邮费
        orderPet.setTotalPrice(pet.getSaleprice().add(new BigDecimal(10)));
        // 获取登录用户
        Logininfo loginContext = LoginContextUtil.getLoginContext();
        if (loginContext == null){
            throw new BasicException("请登陆之后，在重试!");
        }
        orderPet.setUserId(loginContext.getId());
        // 保存订单

        super.insert(orderPet);

        // ===========================构建 保存订单明细========================================
        // 保存订单明细
        OrderPetDetail detail = new OrderPetDetail();
        detail.setCount(1);
        detail.setCreatetime(now);
        // 宠物名
        detail.setName(pet.getName());
        // 订单
        detail.setOrderId(orderPet.getId()); // 获取订单id
        detail.setOrderSn(orderNo); // 创建订单号
        detail.setPetId(pet.getId());
        // 价格
        detail.setPrice(pet.getSaleprice());
        // 图片
        detail.setResources(pet.getResources());
        // 店铺
        detail.setShopId(pet.getShop_id()); // 获取设置Shop id
        detail.setShopName(pet.getName());  // 获取设置Shop Name
        // 保存详情
        orderPetDetailService.insert(detail);

        // =====================================构建保存订单地址==========================================
        // 6.保存订单地址
        OrderAddress orderAddress = new OrderAddress();
        // 拷贝属性
        BeanUtils.copyProperties(userAddress, orderAddress);
        orderAddress.setOrderId(orderPet.getId()); // 设置id
        orderAddress.setOrderSn(orderNo); // 设置订单号
        orderAddress.setCreateTime(now); // 订单时间
        // 保存地址
        orderAddressService.insert(orderAddress);

        //========================================保存一个支付单==============================
        payBillService.save(
                orderPet.getId(),   // 外键
                PayBill.BUSINESS_TYPE_PET, // 业务类型
                "购买："+pet.getName()+"，支付："+orderPet.getTotalPrice(),
                orderPet.getTotalPrice(), // 总价格
                dto.getPayType(),//支付方式用户选的
                pet.getShop().getId() ,// 店铺
                pet.getShop().getName(), // 店铺名
                orderPet.getOrderSn()); // 单号

        //========================================保存一个支付单==============================
        HashMap<String, String> dataMap = new HashMap<>();
        dataMap.put("orderNo", orderNo);
        String jobName = "orderExpireJob" + orderNo;
        dataMap.put("jobName", jobName);

        quartzService.insertOrderExpireJob(
                jobName, // 定时任务名
                OrderExpireJob.class,// 订单超时数据类
                dataMap,// 数据
                payExpireTime// 执行时间
        ); // 单号

        //返回订单号
        return orderNo;
    }
}
